package com.geovis.emergency.spd.controller.pc;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.geovis.common.auth.util.AuthUtil;
import com.geovis.common.core.api.Result;
import com.geovis.common.core.constant.SwaggerConstants;
import com.geovis.common.core.controller.BaseController;
import com.geovis.common.file.handler.IFileHandler;
import com.geovis.common.file.dto.FileDTO;
import com.geovis.common.mybatis.page.PageParam;
import com.geovis.common.mybatis.page.PageResult;
import com.geovis.emergency.spd.biz.pc.service.*;
import com.geovis.emergency.spd.biz.system.service.ISystemFileService;
import com.geovis.emergency.spd.entity.pc.entity.*;
import com.geovis.emergency.spd.entity.pc.pojo.constant.PcMessageConstant;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillQueryDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillSaveDTO;
import com.geovis.emergency.spd.entity.pc.pojo.dto.PcDrillUpdateDTO;
import com.geovis.emergency.spd.entity.pc.pojo.enums.StatusEnum;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PcDrillExportVO;
import com.geovis.emergency.spd.entity.pc.pojo.vo.PcDrillVO;
import com.geovis.emergency.spd.entity.system.constant.SystemFileBusinessConstant;
import com.geovis.emergency.spd.entity.system.entity.SystemFile;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemFileDTO;
import com.geovis.emergency.spd.entity.system.pojo.dto.SystemFileQueryDTO;
import com.geovis.emergency.spd.util.MsgUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 应急预案指挥模块-演练表 前端控制器
 * </p>
 *
 * @author 曾德实
 * @since 2022-04-30
 */
@RestController
    @RequestMapping("/pc/pcDrill")
@RequiredArgsConstructor
@Api(value = "应急预案指挥模块-演练表接口", tags = "应急预案指挥模块-演练表接口")
@Slf4j
@Validated
public class PcDrillController extends BaseController<IPcDrillService> {

    private final IFileHandler fileHandler;
    private final ISystemFileService systemFileService;


    private final IPcDrillDutyOrgService pcDrillDutyOrgService;



    @ApiOperationSupport(order = 1)
    @ApiOperation(value = SwaggerConstants.SAVE_VALUE, notes = SwaggerConstants.SAVE_VALUE)
    @PostMapping({"/save"})
    public Result save(@Validated @RequestBody PcDrillSaveDTO saveDTO) {
        baseService.savePcDrill(saveDTO);
        return Result.ok();
    }

    @ApiOperationSupport(order = 1)
    @ApiOperation(value = SwaggerConstants.UPDATE_VALUE, notes = SwaggerConstants.UPDATE_NOTES)
    @PostMapping({"/update"})
    public Result update(@Validated @RequestBody PcDrillUpdateDTO updateDTO) {
        baseService.updatePcDrill(updateDTO);
        String content= getContent(updateDTO.getId(),"更新");
        MsgUtil.sendDrillMsg(updateDTO.getId(),AuthUtil.getCurrentUserId(),PcMessageConstant.TYPE_DRILL_UPDATE,"更新演练",content,updateDTO.getId());
        return Result.ok();
    }

    private String getContent(String drillId, String opt)
    {
        PcDrill pcDrill=baseService.getById(drillId);
        return "演练【"+pcDrill.getName()+"】已"+opt;
    }

    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "启动演练", notes = "启动演练")
    @PostMapping("/startPcDrill/{drillId}")
    public Result startPcDrill(@PathVariable("drillId") String drillId) {
        baseService.startPcDrill(drillId);
        String content= getContent(drillId,"启动");
        MsgUtil.sendDrillMsg(drillId,null,PcMessageConstant.TYPE_DRILL_START,"启动演练",content,drillId);
        return Result.ok();
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "结束演练", notes = "结束演练")
    @PostMapping("/endPcDrill/{drillId}")
    public Result endPcDrill(@PathVariable("drillId") String drillId) {
        baseService.endPcDrill(drillId);
        String content= getContent(drillId,"结束");
        MsgUtil.sendDrillMsg(drillId,AuthUtil.getCurrentUserId(),PcMessageConstant.TYPE_DRILL_END,"结束演练",content,drillId);
        return Result.ok();
    }

    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "结束演练前校验是否任务未执行", notes = "结束演练前校验是否任务未执行")
    @GetMapping("/checkBeforeEndPcDrill/{drillId}")
    public Result checkBeforeEndPcDrill(@PathVariable("drillId") String drillId) {
        return Result.ok(baseService.checkBeforeEndPcDrill(drillId));
    }

    @ApiOperationSupport(order = 4)
    @ApiOperation(value = SwaggerConstants.LIST_PAGE_VALUE, notes = SwaggerConstants.LIST_PAGE_VALUE)
    @PostMapping("/listPage")
    public Result<PageResult<PcDrillVO>> listPage(@RequestBody @Validated PageParam<PcDrillQueryDTO> pageParam) {
        return Result.ok(baseService.listPage(pageParam));
    }

    @ApiOperationSupport(order = 5)
    @ApiOperation(value = SwaggerConstants.LIST_VALUE, notes = SwaggerConstants.LIST_VALUE)
    @PostMapping("/getList")
    public Result<List<PcDrill>> getList(@RequestBody @Validated PcDrillQueryDTO pageParam) {
        return Result.ok(baseService.getList(pageParam));
    }

    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "根据主键ID查询演练详情", notes = "根据主键ID查询演练详情")
    @PostMapping("/getById/{drillId}")
    public Result<PcDrillVO> getById(@PathVariable("drillId") String drillId) {
        PcDrillVO pcDrillVO = baseService.detailPcDrill(drillId);
        List<String> groupList = pcDrillDutyOrgService.myDutyGroupList(drillId, false);
        if(ObjectUtil.isNotEmpty(groupList)){
            PcDrillDutyOrg drillDutyOrg = pcDrillDutyOrgService.getById(groupList.get(0));
            if (ObjectUtil.isNotNull(drillDutyOrg)){
                pcDrillVO.setDutyOrgName(drillDutyOrg.getOrgName());
            }
        }
//        pcDrillVO.setDutyOrgName("指挥调度组");
        return Result.ok(pcDrillVO);
    }
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "批量删除", notes = "批量删除数据")
    @ApiImplicitParams({@ApiImplicitParam(name = "idList", value = "删除id的list", required = true, dataType = "java.util.Set", paramType = "body")})
    @PostMapping("/removeByIdList")
    public Result removeByIdList(@NotNull(message = "删除的id集合不能为空") @RequestBody Set<String> idList) {
        String drillId=idList.stream().collect(Collectors.toList()).get(0);
        String content= getContent(drillId,"删除");
        MsgUtil.sendDrillMsg(drillId,null,PcMessageConstant.TYPE_DRILL_DELETE,"删除演练",content,drillId);
        baseService.deleteDrill(idList);

        return Result.ok();
    }

    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "根据演练id克隆演练", notes = "根据演练id克隆演练")
    @PostMapping("/cloneDrill/{drillId}")
    public Result cloneDrill(@PathVariable("drillId") String drillId) {
        String cloneDrillId=baseService.clonePcDrill(drillId);
        String title= getContent(cloneDrillId,"创建");
        MsgUtil.sendDrillMsg(cloneDrillId, null, PcMessageConstant.TYPE_DRILL_ADD,title,title,cloneDrillId);
        return Result.ok();
    }

    @ApiOperation(value = "查询附件下载", notes = "查询附件下载")
    @GetMapping(value = "/download/{drillId}")
    public ResponseEntity<byte[]> download(@PathVariable("drillId") String drillId) {
        SystemFileQueryDTO systemFileQueryDTO = new SystemFileQueryDTO();
        systemFileQueryDTO.setRelatedId(drillId);
        systemFileQueryDTO.setType(SystemFileBusinessConstant.TYPE_PC_DRILL);
        List<SystemFileDTO> fileList = systemFileService.getList(systemFileQueryDTO);
        Assert.notEmpty(fileList, "下载失败，该演练内没有附件可下载");
        List<FileDTO> zipList = fileList.stream().map(systemFile -> BeanUtil.copyProperties(systemFile, FileDTO.class)).collect(Collectors.toList());
        return fileHandler.zip(zipList);
    }
    @ApiOperation(value = "暂停或者继续演练", notes = "暂停或者继续演练")
    @GetMapping(value = "/pauseOrPlay/{pcDrillId}")
    public Result pausePlayDrill(@PathVariable("pcDrillId") String pcDrillId){
        PcDrill pcDrill = baseService.getById(pcDrillId);
        Assert.notNull(pcDrill,"演练不存在");
        if (StatusEnum.FALSE.getCode().equals(pcDrill.getIsPause())){
            pcDrill.setIsPause(StatusEnum.TRUE.getCode());
        } else {
            pcDrill.setIsPause(StatusEnum.FALSE.getCode());
        }
        baseService.updateById(pcDrill);

        if (StatusEnum.TRUE.getCode().equals(pcDrill.getIsPause())){
            MsgUtil.sendDrillMsg(pcDrillId,null,PcMessageConstant.TYPE_DRILL_PAUSE,"暂停演练","应急演练【已暂停】",pcDrillId);
        }else {
            MsgUtil.sendDrillMsg(pcDrillId,null,PcMessageConstant.TYPE_DRILL_CONTINUE,"继续演练","继续演练",pcDrillId);
        }
        return Result.ok();
    }
    @ApiOperation(value = "演练预案文档", notes = "演练预案文档")
    @GetMapping(value = "/drillPlanFileList/{pcDrillId}")
    public Result<List<SystemFile>> drillPlanFileList(@PathVariable("pcDrillId") String pcDrillId){
        PcDrill pcDrill = baseService.getById(pcDrillId);
        List<SystemFile> fileList = Lists.newArrayList();
        if (ObjectUtil.isNotNull(pcDrill) && StrUtil.isNotBlank(pcDrill.getPcPlanId())){
            fileList.addAll(getFileList(pcDrill.getPcPlanId(),SystemFileBusinessConstant.TYPE_PLAN_PLANING));
            fileList.addAll(getFileList(pcDrill.getPcPlanId(),SystemFileBusinessConstant.TYPE_PLAN_MANUAL_WORK));
            fileList.addAll(getFileList(pcDrill.getPcPlanId(),SystemFileBusinessConstant.TYPE_PLAN_WORK_RULES));
            fileList.addAll(getFileList(pcDrill.getPcPlanId(),SystemFileBusinessConstant.TYPE_PLAN_OPERATION_MANUAL));
        }
        return Result.ok(fileList);
    }
    @ApiOperation(value = "根据灾害事件查询演练", notes = "根据灾害事件查询演练")
    @GetMapping(value = "/drillListByEventId/{disasterEventId}")
    public Result<List<PcDrillExportVO>> getPcDrillByDisasterEventId(@PathVariable("disasterEventId") String disasterEventId){


//        List<PcDrillDisasterEvent> drillList = pcDrillDisasterEventService.list(
//                Wrappers.lambdaQuery(PcDrillDisasterEvent.class)
//                        .select(PcDrillDisasterEvent::getPcDrillId,PcDrillDisasterEvent::getId,PcDrillDisasterEvent::getPcDisasterEventId)
//                        .eq(PcDrillDisasterEvent::getPcDisasterEventId, disasterEventId)
//        );
//        PcDisasterEvent disasterEvent = pcDisasterEventService.getById(disasterEventId);
//        if (ObjectUtil.isNotNull(disasterEvent)){
//            try {
//                //从科大获取演练推荐
//                String dictValue = DictCache.getDictValue(PcDisasterConstant.DISASTER_TYPE, disasterEvent.getType());
//                List<DrillRecommend> drillRecommend = iflytekService.getDrillRecommend("", dictValue);
//                List<PcDrillExportVO> drillExportList = Lists.newArrayList();
//                for (DrillRecommend recommend : drillRecommend) {
//                    PcDrill pcDrill = baseService.getById(recommend.getDrillId());
//                    if (ObjectUtil.isNotNull(pcDrill)){
//                        PcDrillExportVO pcDrillExportVO = new PcDrillExportVO();
//                        pcDrillExportVO.setId(recommend.getDrillId());
//                        pcDrillExportVO.setRecommend(recommend.getScore());
//                        pcDrillExportVO.setStartNum(recommend.getDrillCount() !=null ? recommend.getDrillCount() : 0);
//                        if(ObjectUtil.isNotNull(recommend.getDrillDate())){
//                            pcDrillExportVO.setLastStartTime(DateUtil.toLocalDateTime(new Date(recommend.getDrillDate())));
//                        }
//                        Optional<PcDrillDisasterEvent> first = drillList.stream().filter(s -> s.getPcDrillId().equals(pcDrill.getId()) && s.getPcDisasterEventId().equals(disasterEventId) ).findFirst();
//                        first.ifPresent(pcDrillDisasterEvent -> pcDrillExportVO.setPcDrillDisasterEventId(pcDrillDisasterEvent.getId()));
//                        drillExportList.add(pcDrillExportVO);
//                    }
//                }
//                if (CollUtil.isNotEmpty(drillExportList)){
//                    return Result.ok(drillExportList);
//                }
//            }catch (Exception e){
//
//            }
//        }
//        List<String> drillIdList = drillList.stream().map(PcDrillDisasterEvent::getPcDrillId).distinct().collect(Collectors.toList());
//        if (CollUtil.isNotEmpty(drillIdList)) {
//            //演练导出次数
//            List<PcDrillExport> drillExportList = pcDrillExportService.list(
//                    Wrappers.lambdaQuery(PcDrillExport.class)
//                            .in(PcDrillExport::getPcDrillId, drillIdList)
//                            .orderByDesc(PcDrillExport::getCreateTime)
//            );
//
//            List<PcDrillExportVO> list = baseService.list(
//                    Wrappers.lambdaQuery(PcDrill.class)
//                            .eq(PcDrill::getStatus,PcDrillConstant.STATUS_COMPLETE)
//                            .in(PcDrill::getId, drillIdList)
//            ).stream().map(drill -> {
//                PcDrillExportVO pcDrillExport = BeanUtil.toBean(drill, PcDrillExportVO.class);
//                List<PcDrillExport> pcDrillExportList = drillExportList.stream()
//                        .filter(s -> s.getPcDrillId().equals(drill.getId()))
//                        .collect(Collectors.toList());
//                pcDrillExport.setStartNum(pcDrillExportList.size());
//                pcDrillExport.setRecommend(3);
//                if (CollUtil.isNotEmpty(pcDrillExportList)){
//                    pcDrillExport.setLastStartTime(pcDrillExportList.get(0).getCreateTime());
//                }
//                Optional<PcDrillDisasterEvent> first = drillList.stream().filter(s -> s.getPcDrillId().equals(drill.getId()) && s.getPcDisasterEventId().equals(disasterEventId) ).findFirst();
//                first.ifPresent(pcDrillDisasterEvent -> pcDrillExport.setPcDrillDisasterEventId(pcDrillDisasterEvent.getId()));
//
//                return pcDrillExport;
//            }).collect(Collectors.toList());
//            return Result.ok(list);
//        }
        return Result.ok(Lists.newArrayList());
    }
    private List<SystemFile> getFileList(String relatedId,String type){
        //获取附件信息
        List<SystemFile> list = systemFileService.getListById(relatedId,type);
        list.sort(Comparator.comparing(SystemFile::getCreateTime));
        return list;
    }



    @ApiOperation(value = "初始化演练角色", notes = "初始化演练角色")
    @GetMapping("/initUserDrillRole")
    public Result initUserDrillRole() {
//        List<String> pliotUsers=Arrays.asList("1520215235795890177","1520215084872249345");
//        List<String> drillUsers=Arrays.asList("1520215472983781378","1520215653032669186");
//        String drillRole="1520213262346498050";
//        String pilotRole="1520213106884620290";
//        List<PcDrill> drills=baseService.list();
//        drills.stream().forEach(drill->{
//
//            pliotUsers.stream().forEach(du->{
//                PcDrillUserRole pdur1=new PcDrillUserRole();
//                pdur1.setUserId(du);
//                pdur1.setPcDrillId(drill.getId());
//                pdur1.setRoleId(pilotRole);
//                pcDrillUserRoleMapper.insert(pdur1);
//            });
//
//        });


        return Result.ok();
    }

}
